# Always print this out before your assignment
sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.5.2
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] knitr_1.33
loaded via a namespace (and not attached):
[1] compiler_4.1.1 here_1.0.1 fastmap_1.1.0 rprojroot_2.0.2 htmltools_0.5.2 tools_4.1.1 yaml_2.2.1 rmarkdown_2.10
[9] xfun_0.25 digest_0.6.27 rlang_0.4.12 evaluate_0.14
getwd()
[1] "/Users/darron/Downloads"
# load all your libraries in this chunk
library('dplyr')
library('tidyverse')
library('utils')
library('rsample')
library('glmnet')
library('glmnetUtils')
library('forcats')
library('rsample')
library('ggplot2')
library('sjPlot')
library('Publish')
library('data.table')
library('psych')
library('partykit')
library('PerformanceAnalytics')
library('rpart')
library('rpart.plot')
library('maptree')
library('randomForestExplainer')
library('rpart')
library('visNetwork')
library('caret')
library('ISLR')
# note, do not run install.packages() inside a code chunk. install them in the console outside of a code chunk.
plays <- read.csv(here::here("Datasets", "plays.csv"))
pff <- read.csv(here::here("Datasets", "PFFscoutingdata.csv"))
head(pff)
NA
DF <- full_join(x = plays,
y = pff,
by = "gameId")
DF2 = select(DF, -5:-7, -10:-21, -25:-29, -32:-43)
DF2 %>% drop_na()
DF2$return_type[DF2$kickReturnYardage < 20] = "Short"
DF2$return_type[DF2$kickReturnYardage > 20 & DF2$kickReturnYardage < 50] = "Medium"
DF2$return_type[DF2$kickReturnYardage > 50] = "Long"
FinalDF <- data.frame(DF2, stringsAsFactors = TRUE) %>%
drop_na() %>%
mutate(return_type = as.factor(return_type),
kickType = as.factor(kickType),
kickContactType = as.factor(kickContactType))
head(FinalDF)
NA
summary(FinalDF)
gameId playId.x playDescription quarter specialTeamsPlayType specialTeamsResult kickLength
Min. :2018090600 Min. : 35 Length:41701 Min. :1.000 Length:41701 Length:41701 Min. : 2.00
1st Qu.:2018112508 1st Qu.: 886 Class :character 1st Qu.:1.000 Class :character Class :character 1st Qu.:48.00
Median :2019102703 Median :1987 Mode :character Median :2.000 Mode :character Mode :character Median :56.00
Mean :2019048212 Mean :1986 Mean :2.444 Mean :54.58
3rd Qu.:2020092712 3rd Qu.:2974 3rd Qu.:3.000 3rd Qu.:63.00
Max. :2021010315 Max. :5456 Max. :5.000 Max. :80.00
kickReturnYardage playResult hangTime kickType kickContactType return_type
Min. :-16.00 Min. :-35.00 Min. :1.220 A:12187 CC :26944 Long :13150
1st Qu.: 5.00 1st Qu.: 35.00 1st Qu.:4.080 N:29480 BF : 7218 Medium:11483
Median : 14.00 Median : 41.00 Median :4.380 R: 34 BB : 2119 Short :17068
Mean : 15.08 Mean : 40.18 Mean :4.317 OOB : 1937
3rd Qu.: 23.00 3rd Qu.: 48.00 3rd Qu.:4.630 CFFG : 1222
Max. :104.00 Max. : 82.00 Max. :5.690 MBDR : 995
(Other): 1266
ggplot(data = FinalDF, aes(x = hangTime, y = kickLength)) + geom_point()

ggplot(data = FinalDF, aes(x = kickLength, y = kickReturnYardage)) + geom_point()

ggplot(data = FinalDF, aes(x = return_type)) + geom_bar()

df_split <- initial_split(FinalDF, prop = 0.75)
df_train <- training(df_split)
df_test <- testing(df_split)
dim(df_train)
[1] 31275 13
dim(df_test)
[1] 10426 13
mod1 <- lm(kickReturnYardage ~ kickLength + hangTime + kickContactType + playResult,
data = df_train)
plot(x = predict(mod1), y = df_train$kickReturnYardage,
xlab='Predicted Values',
ylab='Actual Values',
main='Predicted vs. Actual Values (Training Model)',
col= 1)
abline(a = 0, b = 1)

print(mean((df_train$kickReturnYardage - predict(mod1))^2))
[1] 12.93302
plot(x = predict(mod1, newdata = df_test), y = df_test$kickReturnYardage,
xlab='Predicted Values',
ylab='Actual Values',
main='Predicted vs. Actual Values (Testing Model)',
col= 1)
abline(a = 0, b = 1)

print(mean((df_test$kickReturnYardage - predict(mod1))^2))
Warning in df_test$kickReturnYardage - predict(mod1) :
longer object length is not a multiple of shorter object length
[1] 336.3096
#decision tree 1
#tree_mod_train <- ctree(return_type ~ kickLength + hangTime ,
# data = df_train)
#print(tree_mod_train)
#plot(tree_mod_train)
library('sparkline')
summary_mod_rpart <- rpart(return_type ~ kickLength + hangTime,
data = df_train,
method = "class",
control = list(cp = 0,
minsplit = 10,
maxdepth = 5))
summary_mod_rpart$cptable
CP nsplit rel error xerror xstd
1 0.3887059332 0 1.0000000 1.0000000 0.004691750
2 0.0044539222 1 0.6112941 0.6112941 0.004588429
3 0.0035091508 3 0.6023862 0.6026022 0.004574035
4 0.0004049020 5 0.5953679 0.5954759 0.004561804
5 0.0001619608 7 0.5945581 0.5963397 0.004563308
6 0.0001079739 9 0.5942342 0.5966096 0.004563776
7 0.0000000000 11 0.5940182 0.5973115 0.004564992
plotcp(summary_mod_rpart)

2:16
[1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
visNetwork::visTree(summary_mod_rpart,
nodesPopSize = TRUE,
edgesFontSize = 18,
nodesFontSize = 20,
width = "100%",
height = "1200px")
NA
NA
NA
# Accuracy and other metrics
confusionMatrix(df_test$kickContactType, predictions2)
Confusion Matrix and Statistics
Reference
Prediction BB BC BF BOG CC CFFG DEZ ICC KTB KTC KTF MBC MBDR OOB
BB 6 0 18 0 471 5 0 0 0 0 0 0 0 0
BC 0 1 10 0 40 0 0 0 0 0 0 0 0 0
BF 7 1 224 0 1540 25 0 0 0 0 0 0 1 2
BOG 0 0 1 0 9 0 0 0 0 0 0 0 0 0
CC 4 0 140 0 6616 20 0 0 0 0 0 0 1 3
CFFG 3 0 76 0 211 27 0 0 0 0 0 0 1 2
DEZ 1 0 3 0 106 1 0 0 0 0 0 0 0 0
ICC 0 0 0 0 32 0 0 0 0 0 0 0 0 0
KTB 0 0 1 0 30 0 0 0 0 0 0 0 0 0
KTC 0 0 1 0 61 0 0 0 0 0 0 0 0 0
KTF 0 0 0 0 19 0 0 0 0 0 0 0 0 0
MBC 1 0 1 0 11 0 0 0 0 0 0 0 0 0
MBDR 0 0 5 0 231 1 0 0 0 0 0 0 0 0
OOB 1 0 16 0 429 6 0 0 0 0 0 0 0 4
Overall Statistics
Accuracy : 0.6597
95% CI : (0.6505, 0.6688)
No Information Rate : 0.9405
P-Value [Acc > NIR] : 1
Kappa : 0.103
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: BB Class: BC Class: BF Class: BOG Class: CC Class: CFFG Class: DEZ Class: ICC Class: KTB Class: KTC
Sensitivity 0.2608696 0.50000000 0.45161 NA 0.6747 0.317647 NA NA NA NA
Specificity 0.9525137 0.99520338 0.84129 0.9990409 0.7290 0.971666 0.98935 0.996931 0.997027 0.994053
Pos Pred Value 0.0120000 0.01960784 0.12444 NA 0.9752 0.084375 NA NA NA NA
Neg Pred Value 0.9982873 0.99990361 0.96847 NA 0.1241 0.994261 NA NA NA NA
Prevalence 0.0022060 0.00019183 0.04757 0.0000000 0.9405 0.008153 0.00000 0.000000 0.000000 0.000000
Detection Rate 0.0005755 0.00009591 0.02148 0.0000000 0.6346 0.002590 0.00000 0.000000 0.000000 0.000000
Detection Prevalence 0.0479570 0.00489162 0.17265 0.0009591 0.6507 0.030692 0.01065 0.003069 0.002973 0.005947
Balanced Accuracy 0.6066916 0.74760169 0.64645 NA 0.7019 0.644657 NA NA NA NA
Class: KTF Class: MBC Class: MBDR Class: OOB
Sensitivity NA NA 0.0000000 0.3636364
Specificity 0.998178 0.998753 0.9772618 0.9566011
Pos Pred Value NA NA 0.0000000 0.0087719
Neg Pred Value NA NA 0.9997056 0.9992979
Prevalence 0.000000 0.000000 0.0002877 0.0010551
Detection Rate 0.000000 0.000000 0.0000000 0.0003837
Detection Prevalence 0.001822 0.001247 0.0227316 0.0437368
Balanced Accuracy NA NA 0.4886309 0.6601187
LS0tCnRpdGxlOiAiRmluYWwgUHJvamVjdCBCaWcgRGF0YSBCb3dsIgphdXRob3I6ICJEYXJyb24gS290b3lhbiwgTmljIFZhbWlzLCBPYmFkYSBZb3NlZiIKc3VidGl0bGU6IE1HU0MgMzEwIFByb2JsZW0gU2V0IFRlbXBsYXRlCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKIyBQbGVhc2UgbGVhdmUgdGhpcyBjb2RlIGNodW5rIGFzIGlzLiBJdCBtYWtlcyBzb21lIHNsaWdodCBmb3JtYXR0aW5nIGNoYW5nZXMgdG8gYWx0ZXIgdGhlIG91dHB1dCB0byBiZSBtb3JlIGFlc3RoZXRpY2FsbHkgcGxlYXNpbmcuIAoKbGlicmFyeShrbml0cikKCiMgQ2hhbmdlIHRoZSBudW1iZXIgaW4gc2V0IHNlZWQgdG8geW91ciBvd24gZmF2b3JpdGUgbnVtYmVyCnNldC5zZWVkKDY5NjkpCm9wdGlvbnMod2lkdGg9NzApCm9wdGlvbnMoc2NpcGVuPTk5KQoKCiMgdGhpcyBzZXRzIHRleHQgb3V0cHV0dGVkIGluIGNvZGUgY2h1bmtzIHRvIHNtYWxsCm9wdHNfY2h1bmskc2V0KHRpZHkub3B0cz1saXN0KHdpZHRoLndyYXA9NTApLHRpZHk9VFJVRSwgc2l6ZSA9ICJ2c21hbGwiKSAgCm9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLAogICAgICAgICAgICAgICAjICJjYWNoaW5nIiBzdG9yZXMgb2JqZWN0cyBpbiBjb2RlIGNodW5rcyBhbmQgb25seSByZXdyaXRlcyBpZiB5b3UgY2hhbmdlIHRoaW5ncwogICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIyBhdXRvbWF0aWNhbGx5IGRvd25sb2FkcyBkZXBlbmRlbmN5IGZpbGVzCiAgICAgICAgICAgICAgIGF1dG9kZXAgPSBUUlVFLAogICAgICAgICAgICAgICAjIAogICAgICAgICAgICAgICBjYWNoZS5jb21tZW50cyA9IEZBTFNFLAogICAgICAgICAgICAgICAjIAogICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsCiAgICAgICAgICAgICAgICMgY2hhbmdlIGZpZy53aWR0aCBhbmQgZmlnLmhlaWdodCB0byBjaGFuZ2UgdGhlIGNvZGUgaGVpZ2h0IGFuZCB3aWR0aCBieSBkZWZhdWx0CiAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDUuNSwgIAogICAgICAgICAgICAgICBmaWcuaGVpZ2h0ID0gNC41LAogICAgICAgICAgICAgICBmaWcuYWxpZ249J2NlbnRlcicpCgoKYGBgCgpgYGB7ciBzZXR1cC0yfQoKIyBBbHdheXMgcHJpbnQgdGhpcyBvdXQgYmVmb3JlIHlvdXIgYXNzaWdubWVudApzZXNzaW9uSW5mbygpCmdldHdkKCkKCmBgYAoKCjwhLS0gIyMjIHN0YXJ0IGFuc3dlcmluZyB5b3VyIHByb2JsZW0gc2V0IGhlcmUgLS0+CjwhLS0gWW91IG1heSBleHBvcnQgeW91ciBob21ld29yayBpbiBlaXRoZXIgaHRtbCBvciBwZGYsIHdpdGggdGhlIGZvcm1lciB1c3VhbGx5IGJlaW5nIGVhc2llci4gCiAgICAgVG8gZXhwb3J0IG9yIGNvbXBpbGUgeW91ciBSbWQgZmlsZTogY2xpY2sgYWJvdmUgb24gJ0tuaXQnIHRoZW4gJ0tuaXQgdG8gSFRNTCcgLS0+CjwhLS0gQmUgc3VyZSB0byBzdWJtaXQgYm90aCB5b3VyIC5SbWQgZmlsZSBhbmQgdGhlIGNvbXBpbGVkIC5odG1sIG9yIC5wZGYgZmlsZSBmb3IgZnVsbCBjcmVkaXQgLS0+CgoKYGBge3Igc2V0dXAtM30KCiMgbG9hZCBhbGwgeW91ciBsaWJyYXJpZXMgaW4gdGhpcyBjaHVuayAKbGlicmFyeSgnZHBseXInKQpsaWJyYXJ5KCd0aWR5dmVyc2UnKQpsaWJyYXJ5KCd1dGlscycpCmxpYnJhcnkoJ3JzYW1wbGUnKQpsaWJyYXJ5KCdnbG1uZXQnKQpsaWJyYXJ5KCdnbG1uZXRVdGlscycpCmxpYnJhcnkoJ2ZvcmNhdHMnKQpsaWJyYXJ5KCdyc2FtcGxlJykKbGlicmFyeSgnZ2dwbG90MicpCmxpYnJhcnkoJ3NqUGxvdCcpCmxpYnJhcnkoJ1B1Ymxpc2gnKQpsaWJyYXJ5KCdkYXRhLnRhYmxlJykKbGlicmFyeSgncHN5Y2gnKQpsaWJyYXJ5KCdwYXJ0eWtpdCcpCmxpYnJhcnkoJ1BlcmZvcm1hbmNlQW5hbHl0aWNzJykKbGlicmFyeSgncnBhcnQnKQpsaWJyYXJ5KCdycGFydC5wbG90JykKbGlicmFyeSgnbWFwdHJlZScpCmxpYnJhcnkoJ3JhbmRvbUZvcmVzdEV4cGxhaW5lcicpCmxpYnJhcnkoJ3JwYXJ0JykKbGlicmFyeSgndmlzTmV0d29yaycpCmxpYnJhcnkoJ2NhcmV0JykKbGlicmFyeSgnSVNMUicpCgoKIyBub3RlLCBkbyBub3QgcnVuIGluc3RhbGwucGFja2FnZXMoKSBpbnNpZGUgYSBjb2RlIGNodW5rLiBpbnN0YWxsIHRoZW0gaW4gdGhlIGNvbnNvbGUgb3V0c2lkZSBvZiBhIGNvZGUgY2h1bmsuIAoKYGBgCgoKYGBge3J9CnBsYXlzIDwtIHJlYWQuY3N2KGhlcmU6OmhlcmUoIkRhdGFzZXRzIiwgInBsYXlzLmNzdiIpKQpwZmYgPC0gcmVhZC5jc3YoaGVyZTo6aGVyZSgiRGF0YXNldHMiLCAiUEZGc2NvdXRpbmdkYXRhLmNzdiIpKQpoZWFkKHBmZikKCmBgYAoKYGBge3J9CgpERiA8LSBmdWxsX2pvaW4oeCA9IHBsYXlzLAogICAgICAgICAgICAgICAgIHkgPSBwZmYsCiAgICAgICAgICAgICAgICAgYnkgPSAiZ2FtZUlkIikKCkRGMiA9IHNlbGVjdChERiwgLTU6LTcsIC0xMDotMjEsIC0yNTotMjksIC0zMjotNDMpCgpERjIgJT4lIGRyb3BfbmEoKQoKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA8IDIwXSA9ICJTaG9ydCIKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA+IDIwICYgREYyJGtpY2tSZXR1cm5ZYXJkYWdlIDwgNTBdID0gIk1lZGl1bSIKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA+IDUwXSA9ICJMb25nIgoKRmluYWxERiA8LSBkYXRhLmZyYW1lKERGMiwgc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUpICU+JQogIGRyb3BfbmEoKSAlPiUKICBtdXRhdGUocmV0dXJuX3R5cGUgPSBhcy5mYWN0b3IocmV0dXJuX3R5cGUpLAogICAgICAgICBraWNrVHlwZSA9IGFzLmZhY3RvcihraWNrVHlwZSksCiAgICAgICAgIGtpY2tDb250YWN0VHlwZSA9IGFzLmZhY3RvcihraWNrQ29udGFjdFR5cGUpKQpoZWFkKEZpbmFsREYpCiAgCmBgYAoKCmBgYHtyfQoKc3VtbWFyeShGaW5hbERGKQoKYGBgCgpgYGB7cn0KCmdncGxvdChkYXRhID0gRmluYWxERiwgYWVzKHggPSBoYW5nVGltZSwgeSA9IGtpY2tMZW5ndGgpKSArIGdlb21fcG9pbnQoKQoKYGBgCgoKCmBgYHtyfQoKZ2dwbG90KGRhdGEgPSBGaW5hbERGLCBhZXMoeCA9IGtpY2tMZW5ndGgsIHkgPSBraWNrUmV0dXJuWWFyZGFnZSkpICsgZ2VvbV9wb2ludCgpCgpgYGAKCgpgYGB7cn0KCmdncGxvdChkYXRhID0gRmluYWxERiwgYWVzKHggPSByZXR1cm5fdHlwZSkpICsgZ2VvbV9iYXIoKQpgYGAKCgoKCgpgYGB7cn0KZGZfc3BsaXQgPC0gaW5pdGlhbF9zcGxpdChGaW5hbERGLCBwcm9wID0gMC43NSkKZGZfdHJhaW4gPC0gdHJhaW5pbmcoZGZfc3BsaXQpCmRmX3Rlc3QgPC0gdGVzdGluZyhkZl9zcGxpdCkKCmRpbShkZl90cmFpbikKZGltKGRmX3Rlc3QpCgptb2QxIDwtIGxtKGtpY2tSZXR1cm5ZYXJkYWdlIH4ga2lja0xlbmd0aCArIGhhbmdUaW1lICsga2lja0NvbnRhY3RUeXBlICsgcGxheVJlc3VsdCwKICAgICAgICAgICBkYXRhID0gZGZfdHJhaW4pCgpwbG90KHggPSBwcmVkaWN0KG1vZDEpLCB5ID0gZGZfdHJhaW4ka2lja1JldHVybllhcmRhZ2UsCiAgICAgeGxhYj0nUHJlZGljdGVkIFZhbHVlcycsCiAgICAgeWxhYj0nQWN0dWFsIFZhbHVlcycsCiAgICAgbWFpbj0nUHJlZGljdGVkIHZzLiBBY3R1YWwgVmFsdWVzIChUcmFpbmluZyBNb2RlbCknLAogICAgIGNvbD0gMSkKYWJsaW5lKGEgPSAwLCBiID0gMSkKCnByaW50KG1lYW4oKGRmX3RyYWluJGtpY2tSZXR1cm5ZYXJkYWdlIC0gcHJlZGljdChtb2QxKSleMikpCgpwbG90KHggPSBwcmVkaWN0KG1vZDEsIG5ld2RhdGEgPSBkZl90ZXN0KSwgeSA9IGRmX3Rlc3Qka2lja1JldHVybllhcmRhZ2UsCiAgICAgeGxhYj0nUHJlZGljdGVkIFZhbHVlcycsCiAgICAgeWxhYj0nQWN0dWFsIFZhbHVlcycsCiAgICAgbWFpbj0nUHJlZGljdGVkIHZzLiBBY3R1YWwgVmFsdWVzIChUZXN0aW5nIE1vZGVsKScsCiAgICAgY29sPSAxKQphYmxpbmUoYSA9IDAsIGIgPSAxKQoKcHJpbnQobWVhbigoZGZfdGVzdCRraWNrUmV0dXJuWWFyZGFnZSAtIHByZWRpY3QobW9kMSkpXjIpKQpgYGAKCmBgYHtyfQpwcmVkc190ZXN0IDwtIHByZWRpY3QobW9kMSwgbmV3ZGF0YSA9IGRmX3Rlc3QpCgpwcmVkc19kZiA8LSBkYXRhLmZyYW1lKAogIGBwcmVkaWN0ZWRfdmFsdWVzYCA9IHByZWRzX3Rlc3QsCiAgYGtpY2tfZGlzdGFuY2VfeWFyZHNgID0gZGZfdGVzdCRraWNrTGVuZ3RoCikKCmhlYWQocHJlZHNfZGYpCgpnZ3Bsb3QoZGF0YSA9IHByZWRzX2RmLCBhZXMoeCA9IGtpY2tfZGlzdGFuY2VfeWFyZHMsIHkgPSBwcmVkaWN0ZWRfdmFsdWVzKSkgKyBnZW9tX3BvaW50KCkgKyB0aGVtZV9taW5pbWFsKCkKCiN0b3RhbCA9IDEwNDI2CnByZWRzX2RmICU+JQogIGNvdW50KHByZWRpY3RlZF92YWx1ZXMgPiA1MCkgIzE0OCwgMS40JQoKcHJlZHNfZGYgJT4lCiAgY291bnQocHJlZGljdGVkX3ZhbHVlcyA8IDIwKSAjNzE2MCwgNjguNyUKCnByZWRzX2RmICU+JQogIGNvdW50KGJldHdlZW4ocHJlZGljdGVkX3ZhbHVlcywgMjAsIDUwKSkgIzMxMTgsIDI5LjklCgpgYGAKCgpgYGB7cn0KCmxpYnJhcnkoJ3NwYXJrbGluZScpCgoKc3VtbWFyeV9tb2RfcnBhcnQgPC0gcnBhcnQocmV0dXJuX3R5cGUgfiBraWNrTGVuZ3RoICsgaGFuZ1RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoY3AgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5zcGxpdCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhkZXB0aCA9IDUpKQpzdW1tYXJ5X21vZF9ycGFydCRjcHRhYmxlCgpwbG90Y3Aoc3VtbWFyeV9tb2RfcnBhcnQpCjI6MTYKdmlzTmV0d29yazo6dmlzVHJlZShzdW1tYXJ5X21vZF9ycGFydCwKICAgICAgICAgICAgICAgICAgICBub2Rlc1BvcFNpemUgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIGVkZ2VzRm9udFNpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICBub2Rlc0ZvbnRTaXplID0gMjAsCiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAiMTAwJSIsCiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gIjEyMDBweCIpCgoKCmBgYAoKCgoKYGBge3J9CgpsaWJyYXJ5KCdyYW5kb21Gb3Jlc3QnKQoKbW9kZml0LnJmIDwtIHJhbmRvbUZvcmVzdChraWNrQ29udGFjdFR5cGUgfiAga2lja0xlbmd0aCArIGhhbmdUaW1lLCBkYXRhPWRmX3RyYWluKQoKIyBQcmVkaWN0IHRoZSB0ZXN0aW5nIHNldCB3aXRoIHRoZSB0cmFpbmVkIG1vZGVsCnByZWRpY3Rpb25zMiA8LSBwcmVkaWN0KG1vZGZpdC5yZiwgZGZfdGVzdCwgdHlwZSA9ICJjbGFzcyIpCgojIEFjY3VyYWN5IGFuZCBvdGhlciBtZXRyaWNzCmNvbmZ1c2lvbk1hdHJpeChkZl90ZXN0JGtpY2tDb250YWN0VHlwZSwgcHJlZGljdGlvbnMyKQoKCiNyZl9maXQgPC0gcmFuZG9tRm9yZXN0KGtpY2tDb250YWN0VHlwZSB+IAojICAgICAgICAgICAgICAgICAgICAgIGtpY2tMZW5ndGggKyBoYW5nVGltZSwgCiAjICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3RyYWluLAogIyAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBjbGFzc2lmaWNhdGlvbiwKICMgICAgICAgICAgICAgICAgICAgICAgbXRyeSA9IDQsCiAgIyAgICAgICAgICAgICAgICAgICAgIG5hLmFjdGlvbiA9IG5hLnJvdWdoZml4LAogICMgICAgICAgICAgICAgICAgICAgICBudHJlZSA9IDYwLCAKICAgIyAgICAgICAgICAgICAgICAgICAgaW1wb3J0YW5jZSA9IFRSVUUpCgojcHJpbnQocmZfZml0KQoKI3Bsb3QocmZfZml0KQoKCgojdHJlZV9tb2QyIDwtIGN0cmVlKGtpY2tDb250YWN0VHlwZSB+IGtpY2tMZW5ndGggKyBoYW5nVGltZSwKIyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbikKCiNwcmludCh0cmVlX21vZDIpCiNwbG90KHRyZWVfbW9kMikgCgoKI21vZDIgPC0gbG0obG9nKGtpY2tDb250YWN0VHlwZSkgfiBraWNrTGVuZ3RoICsgaGFuZ1RpbWUsIAogICAgICAgICAgICNkYXRhID0gZGZfdHJhaW4pCiNzdW1tYXJ5KG1vZDIpCgojbW9kZml0LnJwYXJ0IDwtIHJwYXJ0KGNsYXNzZSB+IC4sIGRhdGE9dHJhaW5pbmcsIG1ldGhvZD0iY2xhc3MiLCB4dmFsID0gNCkKI3ByaW50KG1vZGZpdC5ycGFydCwgZGlnaXRzID0gMykKCiNwcmVkaWN0aW9uczEgPC0gcHJlZGljdChtb2RmaXQucnBhcnQsIHRlc3RpbmcsIHR5cGUgPSAiY2xhc3MiKQoKIyBBY2N1cmFjeSBhbmQgb3RoZXIgbWV0cmljcwojY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25zMSwgdGVzdGluZyRjbGFzc2UpCgpgYGAKCgo=